package reesoft.common.code;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 错误码基类，把错误码、描述内容集中在一起以便于维护
 * 定义为类而不是枚举，是为了便于创建派生类，在派生类中定义各个级别范围的错误码
 *
 * Created by reesoft on 2017-07-13
 */
public class ErrorCode
{
    // 错误码映射
    private static final Map<Integer, ErrorCode> errorCodeMap = new ConcurrentHashMap<>();

    // 缺省错误描述是否为英文
    private static boolean englishDesc = false;

    // 静态错误码对象定义，每个错误码只创建一个对象
    public static final ErrorCode SUCCESS = new ErrorCode(0, "成功", "success");
    public static final ErrorCode FAILURE = new ErrorCode(-1, "失败", "failure");
    public static final ErrorCode ACCESS_DENIED = new ErrorCode(4, "没有访问数据的权限", "access denied");
    public static final ErrorCode INVALID_DATA_SIGNATURE = new ErrorCode(8, "数字签名无效", "invalid data signature");
    public static final ErrorCode INVALID_PARAMETER = new ErrorCode(10, "参数无效", "invalid parameter");
    public static final ErrorCode PARAMETER_TOO_SHORT = new ErrorCode(11, "参数没有达到最小长度要求", "parameter too short");
    public static final ErrorCode PARAMETER_TOO_LONG = new ErrorCode(12, "参数超过最大长度限制", "parameter too long");
    public static final ErrorCode INVALID_DATE_FORMAT = new ErrorCode(21, "日期格式无效", "invalid date format");
    public static final ErrorCode INVALID_TIME_FORMAT = new ErrorCode(22, "时间格式无效", "invalid time format");
    public static final ErrorCode INVALID_IP_ADDRESS = new ErrorCode(23, "IP 地址无效", "invalid ip address");
    public static final ErrorCode INVALID_EMAIL = new ErrorCode(24, "邮箱地址无效", "invalid email");
    public static final ErrorCode INVALID_MOBILE_PHONE_NUMBER = new ErrorCode(25, "手机号码无效", "invalid mobile phone number");
    public static final ErrorCode SERVER_INTERNAL_ERROR = new ErrorCode(500, "服务器内部错误", "server internal error");

    // 整型错误码
    private int code;

    // 错误描述（本地语言，中文或其他语言）
    private String desc;

    // 错误描述（英文）
    private String descEng;

    // 构造函数
    public ErrorCode(final int code, final String desc, final String descEng)
    {
        this.code = code;
        this.desc = desc;
        this.descEng = descEng;

        if (errorCodeMap.get(code) != null)
        {
            throw new RuntimeException("Duplicate code defined.");
        }

        errorCodeMap.put(code, this);
    }

    // 派生类用的构造函数，不要通过这个函数来创建对象
    protected ErrorCode()
    {
        throw new RuntimeException("Don't call this ctor.");
    }

    // 取得与整型的错误码相等的错误码对象
    // 如果错误码未定义，将返回空对象
    public static ErrorCode valueOf(final int code)
    {
        return errorCodeMap.get(code);
    }

    // 设置缺省错误描述的语言
    public static void setDefaultDescLanguage(boolean english)
    {
        ErrorCode.englishDesc = english;
    }

    // 判断错误码是否相等
    public boolean equals(final ErrorCode errorCode)
    {
        return this == errorCode
                || code == errorCode.getCode();
    }

    // 判断错误码是否相等
    public boolean equals(final int value)
    {
        return code == value;
    }

    public int getCode()
    {
        return code;
    }

    public String getDesc()
    {
        return getDesc(englishDesc);
    }

    public String getDesc(final boolean english)
    {
        return english ? descEng : desc;
    }

    public String getDescEng()
    {
        return descEng;
    }
}
